
#import "SimAssetsCollectionVC.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import "SimAssetCell.h"
#import "SimMulImagePickerVC.h"
#import "SimPhotoBrowser.h"
#import "UIBarButtonItem+SimAdditions.h"
#import "UIImage+SimAdditions.h"
#import "UIView+SimAdditions.h"
#import "SimLineView.h"

SimImpValue(kSimMulPickerFinishColor, UIColor *)

@interface SimMulImagePickerVC ()

@property (nonatomic, strong) ALAssetsLibrary *assetsLibrary;


@end

@interface SimAssetsCollectionVC () <UICollectionViewDelegateFlowLayout>
{
    UIToolbar * _toolbar;

    UIBarButtonItem *_finishCountItem;
    UIButton *_previewBtn;
    UIButton *_finishCountBtn;
}

@property (nonatomic, copy) NSArray *assets;
@property (nonatomic, assign) NSUInteger numberOfAssets;
@property (nonatomic, assign) NSUInteger numberOfPhotos;
@property (nonatomic, assign) NSUInteger numberOfVideos;

@property (nonatomic, assign) BOOL disableScrollToBottom;
@property (nonatomic, strong) NSIndexPath *indexPathForLastVisibleItem;

@property (strong, nonatomic) NSMutableArray *photos;

@property (strong, nonatomic) NSMutableArray *assetImagesUrl;


@end

@implementation SimAssetsCollectionVC

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.sectionInset = UIEdgeInsetsMake(2, 2, 2, 2);
    layout.minimumLineSpacing = 2.0f;
    layout.minimumInteritemSpacing = 2.0f;
    
    self = [super initWithCollectionViewLayout:layout];
    if (self) {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(assetsLibraryChanged:)
                                                     name:ALAssetsLibraryChangedNotification
                                                   object:nil];

    }
    
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationItem.leftBarButtonItem = [UIBarButtonItem backBarBtnItem:self backStr:@"照片"];
    self.navigationItem.title = [self.assetsGroup valueForProperty:ALAssetsGroupPropertyName];
    self.navigationItem.prompt = self.imagePicker.prompt;
    self.collectionView.allowsMultipleSelection = self.imagePicker.allowsMultipleSelection;
    self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithText:@"取消" target:self action:@selector(doCancel)];
    
    [self setUpToolbarItems];
    [self.collectionView registerClass:[SimAssetCell class] forCellWithReuseIdentifier:@"AssetCell"];
    self.collectionView.backgroundColor = [UIColor whiteColor];
}


- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    [self updateSelectionInfo];
    [self.collectionView reloadData];
    if (self.numberOfAssets > 0 && self.isMovingToParentViewController && !self.disableScrollToBottom) {
        self.disableScrollToBottom = YES;
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:(self.numberOfAssets - 1) inSection:0];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
        });
    }
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
}


- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    self.disableScrollToBottom = YES;
}

- (CGRect)frameForToolbarAtOrientation:(UIInterfaceOrientation)orientation
{
    CGFloat height = 44;
    if (DEVICE_IS_IPHONE && UIInterfaceOrientationIsLandscape(orientation)) height = 32;
    return CGRectIntegral(CGRectMake(0, self.view.bounds.size.height - height, self.view.bounds.size.width, height));
}

- (BOOL)isAssetSelected:(ALAsset *)curAsset
{
    NSMutableArray *selectedAssets = self.imagePicker.selectedAssets;
    for (ALAsset *asset in selectedAssets) {
        if (curAsset == asset) {
            return YES;
        }
        else{
            NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL];
            NSURL *currentURL = [curAsset valueForProperty:ALAssetPropertyAssetURL];
            if ([[currentURL absoluteString] isEqualToString:[assetURL absoluteString]]) {
                return YES;
            }
        }
    }
    
    return NO;
}

#pragma mark - Accessors

- (void)setAssetsGroup:(ALAssetsGroup *)assetsGroup
{
    _assetsGroup = assetsGroup;
    [self updateAssets];
}

- (BOOL)isAutoDeselectEnabled
{
    return (self.imagePicker.maximumNumberOfSelection == 1
            && self.imagePicker.maximumNumberOfSelection >= self.imagePicker.minimumNumberOfSelection);
}


#pragma mark - Handling Device Rotation

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    // Save indexPath for the last item
    self.indexPathForLastVisibleItem = [[self.collectionView indexPathsForVisibleItems] lastObject];
    
    // Update layout
    [self.collectionView.collectionViewLayout invalidateLayout];
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    // Restore scroll position
    [self.collectionView scrollToItemAtIndexPath:self.indexPathForLastVisibleItem atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
}

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    // Save indexPath for the last item
    NSIndexPath *indexPath = [[self.collectionView indexPathsForVisibleItems] lastObject];
    
    // Update layout
    [self.collectionView.collectionViewLayout invalidateLayout];
    
    // Restore scroll position
    [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
    }];
}


#pragma mark - Handling Assets Library Changes

- (void)assetsLibraryChanged:(NSNotification *)notification
{
    dispatch_async(dispatch_get_main_queue(), ^{
        NSSet *updatedAssetsGroups = notification.userInfo[ALAssetLibraryUpdatedAssetGroupsKey];
        NSURL *assetsGroupURL = [self.assetsGroup valueForProperty:ALAssetsGroupPropertyURL];
        
        for (NSURL *updatedAssetsGroupURL in updatedAssetsGroups) {
            if ([updatedAssetsGroupURL isEqual:assetsGroupURL]) {
                [self updateAssets];
                [self.collectionView reloadData];
            }
        }
    });
}



#pragma mark - Toolbar

- (void)setUpToolbarItems
{
    _toolbar = [[UIToolbar alloc] initWithFrame:[self frameForToolbarAtOrientation:self.interfaceOrientation]];
    _toolbar.tintColor = [UIColor whiteColor];
    _toolbar.backgroundColor = [UIColor whiteColor];
    if ([_toolbar respondsToSelector:@selector(setBarTintColor:)]) {
        _toolbar.barTintColor = [UIColor whiteColor];
    }
    if ([[UIToolbar class] respondsToSelector:@selector(appearance)]) {
        [_toolbar setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
        [_toolbar setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsLandscapePhone];
    }
    _toolbar.barStyle = UIBarStyleBlackTranslucent;
    _toolbar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
    for (UIView *view in [_toolbar subviews]) {
        if ([view isKindOfClass:[UIImageView class]]) {
            [view removeFromSuperview];
        }
    }
    [self.view addSubview:_toolbar];
    
    SimLineView *lineView = [[SimLineView alloc] initWithWidth:_toolbar.width];
    [_toolbar addSubview:lineView];
    
    _previewBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 0, 20)];
    _previewBtn.showsTouchWhenHighlighted = YES;
    _previewBtn.titleLabel.font = [UIFont systemFontOfSize:15];
    [_previewBtn setTitleColor:SimValue(kSimMulPickerFinishColor, HEXRGBCOLOR(0x46b789)) forState:UIControlStateNormal] ;
    [_previewBtn setTitleColor:HEXRGBCOLOR(0x999999) forState:UIControlStateDisabled];
    [_previewBtn setTitle:@"预览" forState:UIControlStateNormal];
    [_previewBtn addTarget:self action:@selector(previewSelected) forControlEvents:UIControlEventTouchUpInside];
    [_previewBtn sizeToFit];
    _previewBtn.width += 10;
    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:_previewBtn];
    
    UIBarButtonItem *flexibleSpaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    
    _finishCountBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    _finishCountBtn.titleLabel.font = [UIFont systemFontOfSize:15];
    [_finishCountBtn addTarget:self action:@selector(doFinish) forControlEvents:UIControlEventTouchUpInside];
    [_finishCountBtn setTitle:@"完成(9)" forState:UIControlStateNormal];
    [_finishCountBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [_finishCountBtn setTitleColor:HEXRGBCOLOR(0x999999) forState:UIControlStateDisabled];
    [_finishCountBtn setBackgroundImage:[UIImage imageWithColor:SimValue(kSimMulPickerFinishColor, HEXRGBCOLOR(0x46b789))]
                               forState:UIControlStateNormal];
    [_finishCountBtn setBackgroundImage:[UIImage imageWithColor:HEXRGBCOLOR(0xe7e7e7)]
                               forState:UIControlStateDisabled];
    _finishCountBtn.layer.cornerRadius = 2;
    _finishCountBtn.layer.masksToBounds = YES;
    [_finishCountBtn sizeToFit];
    _finishCountBtn.width += 10;
    _finishCountBtn.height += 10;
    UIBarButtonItem *finishItem = [[UIBarButtonItem alloc] initWithCustomView:_finishCountBtn];
    _toolbar.items = @[leftItem, flexibleSpaceItem, finishItem];
    
    self.collectionView.contentInset = UIEdgeInsetsMake(0, 0, _toolbar.height, 0);
}

- (void)doCancel
{
    if ([self.imagePicker.delegate respondsToSelector:@selector(simImagePickerDidCancel:)]) {
        [self.imagePicker.delegate simImagePickerDidCancel:self.imagePicker];
    }
}

- (void)doFinish
{
    if ([self.imagePicker.delegate respondsToSelector:@selector(simImagePicker:didFinishPickerWithAssets:)]) {
        [self fetchAssetsFromSelectedAssetURLsWithCompletion:^(NSArray *assets) {
            [self.imagePicker.delegate simImagePicker:self.imagePicker didFinishPickerWithAssets:assets];
        }];
    }
}


- (void)previewSelected
{
    NSArray *selectedAssets = [NSMutableArray arrayWithArray:self.imagePicker.selectedAssets];
    if (selectedAssets.count > 0) {
        [self showPhotoBrowserWithContents:selectedAssets
                                     index:0];
    }
}


- (void)updateSelectionInfo
{
    NSMutableArray *selectedAssets = self.imagePicker.selectedAssets;
    if (selectedAssets.count > 0) {
        _finishCountBtn.enabled = YES;
        _previewBtn.enabled = YES;
        [_finishCountBtn setTitle:[NSString stringWithFormat:@"完成(%zd)", selectedAssets.count] forState:UIControlStateNormal];
    } else {
        _finishCountBtn.enabled = NO;
        _previewBtn.enabled = NO;
        [self.navigationController setToolbarHidden:YES animated:YES];
        [_finishCountBtn setTitle:@"完成" forState:UIControlStateNormal];
    }
}


#pragma mark - Fetching Assets
- (void)updateAssets
{
    NSMutableArray *assets = [NSMutableArray array];
    __block NSUInteger numberOfAssets = 0;
    __block NSUInteger numberOfPhotos = 0;
    __block NSUInteger numberOfVideos = 0;
    
    [self.assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
        if (result) {
            numberOfAssets++;
            NSString *type = [result valueForProperty:ALAssetPropertyType];
            if ([type isEqualToString:ALAssetTypePhoto]) numberOfPhotos++;
            else if ([type isEqualToString:ALAssetTypeVideo]) numberOfVideos++;
            [assets addObject:result];
        }
    }];
    
    self.assets = assets;
    self.numberOfAssets = numberOfAssets;
    self.numberOfPhotos = numberOfPhotos;
    self.numberOfVideos = numberOfVideos;
}

- (void)fetchAssetsFromSelectedAssetURLsWithCompletion:(void (^)(NSArray *assets))completion
{
    NSMutableArray *selectedAssets = self.imagePicker.selectedAssets;
    if (completion) {
        completion(selectedAssets);
    }
}


#pragma mark - Checking for Selection Limit

- (BOOL)isMinimumSelectionLimitFulfilled
{
   return (self.imagePicker.minimumNumberOfSelection <= self.imagePicker.selectedAssets.count);
}

- (BOOL)isMaximumSelectionLimitReached
{
    NSUInteger minimumNumberOfSelection = MAX(1, self.imagePicker.minimumNumberOfSelection);
    if (minimumNumberOfSelection <= self.imagePicker.maximumNumberOfSelection) {
        return (self.imagePicker.maximumNumberOfSelection <= self.imagePicker.selectedAssets.count);
    }
   
    return NO;
}

- (void)selectCheckBtn:(UIButton *)checkBtn
{
    CGPoint point = [checkBtn.superview convertPoint:checkBtn.center toView:self.collectionView];
    NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
    BOOL shouldDo =  [self changeSelectStatusForAsset:self.assets[indexPath.row]
                                             selected:!checkBtn.isSelected];
    if (shouldDo) {
        checkBtn.selected = !checkBtn.selected;
    }
}

- (BOOL)changeSelectStatusForAsset:(ALAsset *)asset selected:(BOOL)selected
{
    if (selected) {
        if ([self shouldSelectAsset:asset]) {
            [self selectAsset:asset];
        }
        else{
            return NO;
        }
    } else{
        [self deselectItemAsset:asset];
    }
    
    return YES;
    
}


- (void)selectAsset:(ALAsset *)asset
{
    SimMulImagePickerVC *imagePicker = self.imagePicker;
    NSMutableArray *selectedAssets = imagePicker.selectedAssets;
    
    if (imagePicker.allowsMultipleSelection) {
        if ([self isAutoDeselectEnabled] && selectedAssets.count > 0) {
            [selectedAssets removeObjectAtIndex:0];
        }
        
        [selectedAssets addObject:asset];
        [self updateSelectionInfo];

    } else {
        if ([imagePicker.delegate respondsToSelector:@selector(simImagePicker:didFinishPickerWithAssets:)]) {
            [imagePicker.delegate simImagePicker:imagePicker didFinishPickerWithAssets:@[asset]];
        }
    }
}

- (BOOL)shouldSelectAsset:(ALAsset *)asset
{
    if (asset.defaultRepresentation.fullScreenImage == nil){
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"图片出错了,不能选择" message:nil delegate:nil cancelButtonTitle:@"好的" otherButtonTitles:nil];
        [alertView show];
        return NO;
    }
    
    if ([self.imagePicker.delegate respondsToSelector:@selector(simImagePicker:shouldSelectAsset:)]) {
        return [self.imagePicker.delegate simImagePicker:self.imagePicker shouldSelectAsset:asset];
    }
    
    if ([self isAutoDeselectEnabled]) {
        return YES;
    }
    
    return ![self isMaximumSelectionLimitReached];
}

- (void)deselectItemAsset:(ALAsset *)asset{
    if (!self.imagePicker.allowsMultipleSelection) {
        return;
    }
    
    SimMulImagePickerVC *imagePicker = self.imagePicker;
    [imagePicker.selectedAssets removeObject:asset];
    [self updateSelectionInfo];
}

- (void)showPhotoBrowserWithContents:(NSArray *)assets index:(NSInteger)index
{
    SimPhotoBrowser *photoBrowserVC = [[SimPhotoBrowser alloc] initWithImageContents:assets index:index];
    photoBrowserVC.enableSelect = YES;
    photoBrowserVC.enableSave = NO;
    DefineWeak(self);
    photoBrowserVC.isSelectedForIndex = ^(SimPhotoBrowser *browser, NSInteger index){
        ALAsset *asset = assets[index];
        if ([Weak(self) isAssetSelected:asset]) {
            return YES;
        }
        return NO;
    };
    photoBrowserVC.selectedStatusChanged = ^(SimPhotoBrowser *browser, NSInteger index, BOOL selected){
        ALAsset *asset = assets[index];
        return [Weak(self) changeSelectStatusForAsset:asset
                                             selected:selected];
    };
    photoBrowserVC.allSelectCount = ^(SimPhotoBrowser *browser){
        return Weak(self).imagePicker.selectedAssets.count;
    };
    photoBrowserVC.didFinishBrowser = ^(SimPhotoBrowser *browser, BOOL hasChanged){
        [Weak(self) doFinish];
    };
    
    [self.navigationController pushViewController:photoBrowserVC animated:YES];
}


#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.numberOfAssets;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    SimAssetCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AssetCell" forIndexPath:indexPath];
    cell.tag = indexPath.item;
    DefineWeak(self);
    cell.clickOnCheckBtn = ^(UIButton *checkBtn){
        [Weak(self) selectCheckBtn:checkBtn];
    };
    
    // Image
    ALAsset *asset = self.assets[indexPath.item];
    UIImage *image = [UIImage imageWithCGImage:[asset thumbnail]];
    cell.imageView.image = image;
    
    // Video indicator
    NSString *assetType = [asset valueForProperty:ALAssetPropertyType];
    if ([assetType isEqualToString:ALAssetTypeVideo]) {
        cell.videoView.hidden = NO;
        
        NSTimeInterval duration = [[asset valueForProperty:ALAssetPropertyDuration] doubleValue];
        NSInteger minutes = (NSInteger)(duration / 60.0);
        NSInteger seconds = (NSInteger)ceil(duration - 60.0 * (double)minutes);
        cell.videoTime = [NSString stringWithFormat:@"%02ld:%02ld", (long)minutes, (long)seconds];
    } else {
        cell.videoView.hidden = YES;
    }
    
    [cell.checkBtn setSelected:[self isAssetSelected:asset]];

    return cell;
}

#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    [self showPhotoBrowserWithContents:self.assets index:indexPath.row];
}

#pragma mark - UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger numberOfColumns;
    if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) {
        numberOfColumns = self.imagePicker.numberOfColumnsInPortrait;
    } else {
        numberOfColumns = self.imagePicker.numberOfColumnsInLandscape;
    }
    
    CGFloat width = (CGRectGetWidth(collectionView.frame) - 2.0 * (numberOfColumns + 1)) / numberOfColumns;
    
    return CGSizeMake(width, width);
}

@end
